/**
 * @user Dahai CAO
 * @date 07/07/2011 3:26:34 PM
 */
package com.salary.utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class FileUtil {
	/**
	 * Copy file from the source directory <tt>src</tt> to the destined
	 * directory <tt>dest</tt>.
	 * 
	 * @param src
	 *            source directory
	 * @param dest
	 *            destined directory
	 * @throws IOException
	 */
	public static void copyFile(String src, String dest) throws IOException {
		FileInputStream in = new FileInputStream(src);
		File file = new File(dest);
		if (!file.exists())
			file.createNewFile();
		FileOutputStream out = new FileOutputStream(file);
		int c;
		byte buffer[] = new byte[1024];
		while ((c = in.read(buffer)) != -1) {
			for (int i = 0; i < c; i++)
				out.write(buffer[i]);
		}
		in.close();
		out.close();
	}

	/**
	 * Write a specified file to a specified directory. This method is used in
	 * upload a file to a server.
	 * 
	 * @param bytes
	 * @param dest
	 * @param filename
	 * @throws IOException
	 */
	public static void writeFile(byte[] bytes, String dest, String filename) throws IOException {

		// Path path = Paths.get("C:/temp/test.txt");
		// byte[] data = Files.readAllBytes(path);

		// Using FileUtils.readFileToByteArray()
		// byte[] org.apache.commons.io.FileUtils.readFileToByteArray(File file)

		// Using IOUtils.toByteArray
		// byte[] org.apache.commons.io.IOUtils.toByteArray(InputStream input)

		BufferedOutputStream buffStream = new BufferedOutputStream(new FileOutputStream(dest + "/" + filename));
		buffStream.write(bytes);
		buffStream.close();
	}

	/**
	 * Create file directory using specified <tt>path</tt>.
	 * 
	 * @param path
	 *            directory.
	 */
	public static File createDir(String path) {
		File dir = new File(path);
		if (!dir.exists())
			dir.mkdir();
		return dir;

	}

	/**
	 * Delete file by the specified <tt>file name</tt> in the specified
	 * directory <tt>path</tt>.
	 * 
	 * @date 07/07/2011 3:41:11 PM
	 * @param path
	 *            directory
	 * @param filename
	 *            file name.
	 */
	public static void delFile(String path, String filename) {
		File file = new File(path + "/" + filename);
		if (file.exists() && file.isFile()) {
			file.delete();
		}

	}

	// 删除文件名包含指定字符的文件
	public static void deleteFilesLikeName(File file, String likeName) {
		if (file.isFile()) {
			// 是文件
			String temp = file.getName().substring(0, file.getName().lastIndexOf("."));
			if (temp.indexOf(likeName) != -1) {
				file.delete();
			}
		} else {
			// 是目录
			File[] files = file.listFiles();
			for (int i = 0; i < files.length; i++) {
				deleteFilesLikeName(files[i], likeName);
			}
		}
	}

	// 删除某目录下文件名字包含指定字符的文件
	public static void deleteDirFilesLikeName(String dir, String likeName) {
		File file = new File(dir);
		if (file.exists()) {
			deleteFilesLikeName(file, likeName);
		} else {
			//System.out.println("路径不存在");
		}
	}

	/**
	 * Delete file directory by the specified directory <tt>path</tt>.
	 * 
	 * @date 07/07/2011 3:44:09 PM
	 * @param path
	 */
	public static void delDir(String path) {
		File dir = new File(path);
		if (dir.exists()) {
			File[] tmp = dir.listFiles();
			for (int i = 0; i < tmp.length; i++) {
				if (tmp[i].isDirectory()) {
					delDir(path + "/" + tmp[i].getName());
				} else {
					tmp[i].delete();
				}
			}
			dir.delete();
		}
	}

	/**
	 * 
	 * @date 07/07/2011 4:07:53 PM
	 * @param path
	 * @return
	 * @throws IOException
	 */
	public static String FileInputStream(String path) throws IOException {
		File file = new File(path);
		if (!file.exists() || file.isDirectory())
			throw new FileNotFoundException();
		FileInputStream fis = new FileInputStream(file);
		byte[] buf = new byte[1024];
		StringBuffer sb = new StringBuffer();
		while ((fis.read(buf)) != -1) {
			sb.append(new String(buf));
			buf = new byte[1024];// 重新生成，避免和上次读取的数据重复
		}
		fis.close();
		return sb.toString();
	}

	public static byte[] BytesFromFile(File file) throws IOException {
		InputStream is = new FileInputStream(file);
		long length = file.length();

		if (length > Integer.MAX_VALUE) {
			System.out.println("Sorry! Your given file is too large.");
			System.exit(0);
		}

		byte[] bytes = new byte[(int) length];
		int offset = 0;
		int numRead = 0;
		while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
			offset += numRead;
		}
		if (offset < bytes.length) {
			is.close();
			throw new IOException("Could not completely read file " + file.getName());
		}
		is.close();
		return bytes;
	}

	/**
	 * List all file names with the specified <tt>extension</tt> in the
	 * specified directory <tt>path</tt>. The format of extension is "." plus
	 * file extension name, ";" as a separator. For example: ".jpg", or
	 * ".jpg;.gif;.pdf", etc.
	 * 
	 * @date 07/07/2011 4:15:23 PM
	 * @param path
	 * @return
	 * @throws IOException
	 */
	public static String[] readFileNames(String path, final String ext) throws IOException {
		File fileDir = new File(path);
		if (fileDir.isDirectory()) {
			FileFilter fileFilter = new FileFilter() {
				public boolean accept(File file) {
					if (file.isFile()) {
						StringTokenizer st = new StringTokenizer(ext, ";");
						while (st.hasMoreTokens()) {
							String ext = st.nextToken();
							if (file.getName().endsWith(ext))
								return true;
						}
					}
					return false;
				}
			};
			File[] t = fileDir.listFiles(fileFilter);
			if (t.length > 0) {
				String[] filenames = new String[t.length];
				for (int i = 0; i < t.length; i++) {
					filenames[i] = t[i].getName();
				}
				return filenames;
			}
		}
		return null;
	}

	/**
	 * Returns size string format of <code>filesize<code>.
	 * 
	 * @date 04/03/2012 12:27:03 PM
	 * @return String
	 */
	public static String computingSize(long filesize) {
		long size = filesize;
		if (size < 1024)
			return size + " byte";
		else {
			String r = " K";
			double d = (size * 1.0) / 1024;
			BigDecimal mData = new BigDecimal(String.valueOf(d)).setScale(2, BigDecimal.ROUND_HALF_UP);
			NumberFormat nf1 = NumberFormat.getInstance();
			return nf1.format(mData) + r;
		}
	}

	public static List<File> getFileList(final String filepath, final String ext) {
		List<File> files = new ArrayList<File>();
		files.clear();
		File file = new File(filepath);
		loopFiles(file, ext, files);
		return files;
	}

	/**
	 * This method can get all jar files in the sepecific folder including all
	 * subfolders
	 * 
	 * @param file
	 * @param ext
	 * @param fileList
	 */
	private static void loopFiles(File file, final String ext, List<File> fileList) {
		if (file.exists()) {
			if (file.isDirectory()) {
				FileFilter fileFilter = new FileFilter() {
					public boolean accept(File file) {
						if (file.isFile()) {
							StringTokenizer st = new StringTokenizer(ext, ";");
							while (st.hasMoreTokens()) {
								String extendname = st.nextToken();
								if (file.getAbsolutePath().endsWith(extendname))
									return true;
							}
						}
						return false;
					}
				};
				File[] files = file.listFiles(fileFilter);
				for (File tmp : files)
					loopFiles(tmp, ext, fileList);
			} else {
				fileList.add(file);
				// addURL(file);
			}
		}
	}
}
